#include "access.h"


#include "vstring.h"

/*atualizar a lista encadeada com novas informaçoes*/
void refresh_list()
{
    //bloqueia o servidor para que não haja leituras na lista
    //enquanto estiver atualizando os registros
    pthread_mutex_lock(&access_semaphore);
    clear_accesslist();
    create_access_list();
    printf("Lista de Acessos Atualizada!\n");
    pthread_mutex_unlock(&access_semaphore);
    //libera o mutex apos atualizar
}


/* extrai as informações da linha do arquivo access list */
void get_archive_line(vstring* line)
{
    list *aux;

    aux = (list *) malloc(sizeof(list));
    aux->url = new_vstring();
    aux->next = NULL;

    /*se a URL for Allow */
    if(remove_occour(&line,"ALLOW"))
        aux->type = 1;
    else
        if(remove_occour(&line,"DENY"))
            aux->type = 0;

    remove_occour(&line,EQUAL);
    trim(&line);

    aux->asterisc_begin = 0;
    if(line->pt[0] == '*')
    {
        aux->asterisc_begin = 1;
        remove_occour(&line,ASTERISK);
    }
    copy_vstring(&(aux->url),line);    
    
    //Inserção dos Dados na Lista
    if(root == NULL)
        root = aux;
    else
    {
        aux->next = root;
        root  = aux;
    }	
}

/*Busca a Url na Lista de Acessos e verifica se ela é permitada ou não*/
int has_permission(vstring* url)
{
    //cria um ponteiro temp e o inicia com a posicao da raiz da lista
    list *temp = root;

    //caso em que as comparações serão com urls exatamente identicas.
    while (temp != NULL)
    {
        if(strcmp(temp->url->pt,url->pt) == 0)
        {
            if(temp->type == 0)
                return 0;
            return 1;
        }
        temp = temp->next;
    }

    //reinicializa o ponteiro temp
    temp = root;

    //caso que trata trechos de urls que estão em outras
    while (temp != NULL)
    {
        int i = 0;
        char *occur = NULL;

        if((occur = strstr(url->pt,temp->url->pt)) != NULL)
        {
            i = occur - url->pt;

            //se o url do access for negado
            if(temp->type == 0)
            {
                //verifica se o url cliente faz parte do dominio
                if(url->pt[i + temp->url->length] == '/' || url->pt[i + temp->url->length] == '\0')
                    return 0;
            }
        }
        temp = temp->next;
    }
    return 1;
}

/*Remove todo o conteudo da Lista Encadeada de Acessos*/
void clear_accesslist()
{
      while (root != NULL) 
      {
          list *temp = root;
          root = root->next;
          free(temp);
      }
    
     root = NULL;
     printf("Lista de Acessos Limpa!\n");
}


void print()
{
      list *ptr;

      if (root == NULL)
      {
        printf("--- fim da lista ---\n\n");
        return;
      }

      // Caso a lista nao esteja vazia
      ptr = root;
      while (ptr != NULL) 
      {
         printf("Url = %s\n",ptr->url->pt);
         printf("Type = %d\n",ptr->type); 
	 printf("Asterisco = %d\n\n",ptr->asterisc_begin); 
         ptr = ptr->next;
      }
      
      printf("--- fim da lista ---\n\n");
}
  
  
/*Retira as informações relevantes do arquivo para criar a lista na memoria*/
void create_access_list()
{
    vstring *line = NULL,*data = NULL,*access_conf = NULL;

    copy_string(&access_conf,ACCESSLIST);
    root = NULL;
    // leitura do arquivo de configuração, conteúdo é copiado para *data
    read_file(access_conf,&data);
    // enquanto o arquivo contiver linhas para serem analisadas...

    while(get_line(&line,&data))
    {
        remove_comment(&line);
        trim(&line);
        // verifica se ainda tem informação para ser processada

        if(line != NULL)
            get_archive_line(line);
    }
}
